<template>
  <div class="websocket-container">
    <!--导航栏-->
    <van-nav-bar class="login-nav-bar" title="小聪同学"><van-icon slot="left" name="arrow-left" @click="$router.back()" /></van-nav-bar>
    <!-- 消息列表 -->
    <van-cell-group class="message-list" ref="message-list">
      <div class="chat-item" :class="[{left: item.name != 'my'}, {right: item.name === 'my'}]" v-for="(item, index) in messages" :key="index">
        <van-image fit="cover" round v-if='item.name != "my"' :src="xcAvatar"></van-image>
        <div class="chat-pao">{{item.msg}}</div>
        <van-image fit="cover" round v-if='item.name === "my"' :src="photo"></van-image>
      </div>
    </van-cell-group>
    <!-- /消息列表 -->
    <!-- 发送消息 -->
    <van-cell-group class="send-message-wrap">
      <van-field v-model="message" placeholder="请输入消息" :border="false" />
      <van-button type="primary" size="small" @click="onSend">发送</van-button>
    </van-cell-group>
    <!-- /发送消息 -->
  </div>
</template>

<script>
// socket.io即时通讯
import io from 'socket.io-client'
// 调用本地存储
import { getItem, setItem } from '@/utils/storage'
// 用容器的 mapState 方法映射到组件中
import { mapState } from 'vuex'
// 调用用户信息 api
import { getUserInfo } from '@/api/user'

// 发送消息
// socket.emit('消息类型', 消息内容)
// socket.on('消息类型', function (data) { data消息 })

export default {
  name: 'Websocket',
  components: {},
  data () {
    return {
      message: '',
      socket: null, // WebSocket 通信对象
      messages: getItem('chat-messages') || [], // 消息列表
      photo: null, // 我的头像
      xcAvatar: require('@/assets/icon.jpg') // 小聪头像
    }
  },
  computed: {
    ...mapState(['user'])
  },
  watch: {
    messages () {
      setItem('chat-messages', this.messages)

      // 如果你要在操作数据之后立即操作数据影响的视图 DOM，那么最好把代码放到 nextTick 函数中
      // 数据改变影响视图更新这件事儿不是立即的
      this.$nextTick(() => {
        this.scrollToBottom()
      })
    }
  },
  created () {
    // 如果用户登录了，则请求加载用户信息数据
    if (this.user) {
      this.loadUserInfo()
    }
    // 建立连接
    // 获取本地存储token
    const token = localStorage.getItem('token')
    // const socket = io('http://toutiao.itheima.net')
    const socket = io('http://toutiao.itheima.net', {
      query: {
        // 用户token
        token
        // token: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NDMyODQzNjYsInVzZXJfaWQiOjF9.mLYitrKsn4E4KdQd0CNPugKrH8uQmXEQTlG_JutC8jU'
      },
      transports: ['websocket']
    })
    this.socket = socket

    socket.on('connect', () => {
      console.log('连接建立成功了')
    })

    // 断开连接了
    socket.on('disconnect', () => {
      console.log('断开连接了')
    })

    // 监听 message 事件，接收服务端消息
    socket.on('message', data => {
      // 把对方发给我的消息放到数组中
      this.messages.push(data)
    })
  },
  mounted () {
    this.scrollToBottom()
  },
  methods: {
    // 用户信息
    async loadUserInfo () {
      try {
        const { data } = await getUserInfo()
        // console.log(data)
        this.photo = data.data.photo
      } catch (err) {
        this.$toast('获取数据失败，请稍后重试！')
      }
    },
    onSend () {
      // 请求发送消息
      const data = {
        name: 'my',
        msg: this.message,
        timestamp: Date.now()
      }
      this.socket.emit('message', data)

      // 把用户发出去的消息存储到数组中
      this.messages.push(data)

      // 清空输入框
      this.message = ''
    },

    scrollToBottom () {
      const list = this.$refs['message-list']
      list.scrollTop = list.scrollHeight
    }
  },
  // 关闭页面，关闭链接
  destroyed () {
    this.socket.close()
  }
}
</script>

<style scoped lang="less">
.websocket-container{
  width: 100%;
  padding-top: 46px;
  .login-nav-bar{
    width: 100%;
    position: fixed;
    left: 0;
    top: 0;
    z-index: 10;
  }
  .avatar{
    width: 30px;
    height: 30px;
  }
}
.message-list{
  position: fixed;
  left: 0;
  right: 0;
  top: 46px;
  bottom: 44px;
  overflow-y: auto;
}
.message-list::after{
  display: none;
}
.send-message-wrap{
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  padding: 0 14px 0 5px;
  align-items: center;
}
.van-button--primary{
  width: 60px;
}
.chat-item{
  padding: 10px;
}
.chat-item .van-image{
  vertical-align: top;
  display: inline-block;
  width: 40px;
  height: 40px;
  border-radius: 50%;
}
.chat-item .chat-pao{
  vertical-align: top;
  display: inline-block;
  min-width: 46px;
  max-width: 70%;
  min-height: 20px;
  line-height: 20px;
  border-radius: 5px;
  position: relative;
  padding: 10px;
  background-color: #f7f8fa;
  word-break: break-all;
  font-size: 14px;
  color: #333;
  box-sizing: border-box;
}
.chat-item .chat-pao::before{
  content: "";
  width: 8px;
  height: 8px;
  position: absolute;
  top: 16px;
  background: #f7f8fa;
}
.chat-item.left .chat-pao{
  margin-left: 10px;
}
.chat-item.right .chat-pao{
  margin-right: 10px;
}
.chat-item.left .chat-pao::before{
  left: -4px;
  transform: rotate(-135deg);
}
.chat-item.right .chat-pao::before{
  right: -4px;
  transform: rotate(45deg);
}
.chat-item.left{
  text-align: left;
}
.chat-item.right{
  text-align: right;
}
</style>
